﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Somnus.Objects;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Somnus.Core.Pause
{
    class PauseParticle : Objeto2D
    {
        //Verifica de a classe já foi inicializada
        private static bool initialized = false;

        //Lista de particulas
        public static List<PauseParticle> particleList;

        //textura das particulas
        public static Texture2D particleTexture;

        public static Random random;

        private static int BLUR_RADIUS;
        public static float blurAmount;
        private static GaussianBlur gaussianBlur;
        private static RenderTarget2D renderTarget1;
        private static RenderTarget2D renderTarget2;
        private static int renderTargetWidth;
        private static int renderTargetHeight;
        private static RenderTarget2D pauseRenderTarget;
        private static Texture2D finalParticleTexture;

        



        public static void Initialize(GraphicsDevice graphicsDevice)
        {
            if (!initialized)
            {
                particleList = new List<PauseParticle>();
                particleTexture = Game1.getInstance().Content.Load<Texture2D>("particula");
                random = new Random();
                gaussianBlur = new GaussianBlur(Game1.getInstance());
                BLUR_RADIUS = 2;
                blurAmount = 3f;
                InitRenderTargets(graphicsDevice);
                pauseRenderTarget = new RenderTarget2D(graphicsDevice, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, false, SurfaceFormat.Color, DepthFormat.None);

                gaussianBlur.ComputeKernel(BLUR_RADIUS, blurAmount);
                InitRenderTargets(Game1.getInstance().GraphicsDevice);

                GenerateFirstRow();
                
            }
        }

        public static void Update(GameTime gameTime)
        {
            for (int i = 0; i < particleList.Count; i++)
            {
                particleList[i].update();
            }

            if (gameTime.TotalGameTime.Milliseconds % 7 == 0)
                createParticle();
        }

        public static void createParticle()
        {
            PauseParticle particula = new PauseParticle();
            particula.x = random.Next(0, Game1.getInstance().graphics.PreferredBackBufferWidth);
            particula.y = -10;
            particleList.Add(particula);
        }

        private static void InitRenderTargets(GraphicsDevice graphicsDevice)
        {
            // Since we're performing a Gaussian blur on a texture image the
            // render targets are half the size of the source texture image.
            // This will help improve the blurring effect.

            renderTargetWidth = graphicsDevice.PresentationParameters.BackBufferWidth / 2;
            renderTargetHeight = graphicsDevice.PresentationParameters.BackBufferHeight / 2;

            renderTarget1 = new RenderTarget2D(graphicsDevice,
                renderTargetWidth, renderTargetHeight, false,
                graphicsDevice.PresentationParameters.BackBufferFormat,
                DepthFormat.None);

            renderTarget2 = new RenderTarget2D(graphicsDevice,
                renderTargetWidth, renderTargetHeight, false,
                graphicsDevice.PresentationParameters.BackBufferFormat,
                DepthFormat.None);

            // The texture offsets used by the Gaussian blur shader depends
            // on the dimensions of the render targets. The offsets need to be
            // recalculated whenever the render targets are recreated.

            gaussianBlur.ComputeOffsets(renderTargetWidth, renderTargetHeight);
        }

        private static void GenerateFirstRow()
        {
            for (int i = 0; i < 25; i++)
            {
                PauseParticle particula = new PauseParticle();
                particula.x = random.Next(0, Game1.getInstance().graphics.PreferredBackBufferWidth);
                particula.y = random.Next(0, Game1.getInstance().graphics.PreferredBackBufferWidth / 13);
                particleList.Add(particula);
            }
        }










        
        private Vector2 velocity;
        private float mass;

        public PauseParticle()
            : base(particleTexture, null, 0.5f)
        {
            
            this.Width = this.Height = random.Next(5, 25);
            this.mass = this.Width + (random.Next(-2, 2));
            
            this.alpha = randomNumber(0.6f, 1f);
            this.alpha -= this.mass / 60;

            velocity = new Vector2(randomNumber(-0.1f, 0.1f), randomNumber(0.3f, 0.5f) - this.mass / 65);
            this.color = Color.Lerp(Color.Aquamarine, Color.White, randomNumber(0.2f, 1));
            this.color = Color.Lerp(this.color, Color.RoyalBlue, randomNumber(0, 0.4f));
        }

        public void update()
        {
            this.y += velocity.Y + randomNumber(-0.02f, 0.02f);
            this.x += velocity.X + randomNumber(-0.02f, 0.02f);
            this.alpha -= randomNumber(0, 0.0006f);
           
            
            if (alpha <= 0)
            {
                particleList.Remove(this);
            }
        }





        public static Texture2D drawParticles(GameTime gameTime, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {
            
            graphicsDevice.SetRenderTarget(pauseRenderTarget);
            graphicsDevice.Clear(Color.Transparent);

            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Additive);
            //Desenha o jogo nesse novo render target
            foreach (PauseParticle pp in particleList)
            {
                pp.draw(gameTime, spriteBatch);
            }
            spriteBatch.End();

            //Salva o render target em uma textura
            finalParticleTexture = pauseRenderTarget as Texture2D;

            
            //Seta o renderTarget para o BackBuffer
            graphicsDevice.SetRenderTarget(null);

            
            
            
            
            
            Texture2D resuld = gaussianBlur.PerformGaussianBlur(finalParticleTexture, renderTarget1, renderTarget2, spriteBatch);

            

            //spriteBatch.Draw(finalParticleTexture, Vector2.Zero, Color.White);
            return resuld;
        }

        public float randomNumber(float minimum, float maximum)
        {
            return (float)(random.NextDouble() * (maximum - minimum) + minimum);
        }


    }
}
